package com.kye.express.business.welfare_integral;

import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.annotation.IntRange;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.LinearLayoutManager;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;

import com.jakewharton.rxbinding2.view.RxView;
import com.kye.base.DebounceObservableTransformer;
import com.kye.base.Logger;
import com.kye.base.utils.DateUtils;
import com.kye.base.utils.GsonUtils;
import com.kye.express.R;
import com.kye.express.business.base.BaseToolbarActivity;
import com.kye.express.business.jd.order_detail.JDOrderDetailActivity;
import com.kye.express.business.jd.order_detail.model.JDOrderDetailModel;
import com.kye.express.business.welfare_integral.viewbinder.IntegralHeaderItemViewBinder;
import com.kye.express.business.welfare_integral.viewbinder.IntegralRecordEmptyItemViewBinder;
import com.kye.express.business.welfare_integral.viewbinder.IntegralRecordExchangeItemViewBinder;
import com.kye.express.business.welfare_integral.viewbinder.IntegralRecordObtainItemViewBinder;
import com.kye.express.business.welfare_integral.viewbinder.IntegralTabItemViewBinder;
import com.kye.express.business.welfare_integral_strategy.IntegralStrategyActivity;
import com.kye.express.databinding.ActivityIntegralCenterBinding;
import com.kye.express.view.KyeProgressDialog;
import com.kye.express.view.ToastManager;
import com.kye.lib.view.statuslayout.StatusLayout;
import com.kye.model.base.PageInfo;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.integral.IntegralHeaderBean;
import com.kye.model.bean.integral.IntegralItemType;
import com.kye.model.bean.integral.IntegralObtainType;
import com.kye.model.bean.integral.IntegralRecordEmptyBean;
import com.kye.model.bean.integral.IntegralRecordExchangeRecordBean;
import com.kye.model.bean.integral.IntegralRecordObtainRecordBean;
import com.kye.model.bean.integral.IntegralRecordStatusBean;
import com.kye.model.bean.integral.IntegralRecordType;
import com.kye.model.bean.integral.IntegralUpdateByUser;
import com.kye.model.bean.user.User;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnRefreshLoadmoreListener;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;

import net.yslibrary.android.keyboardvisibilityevent.util.UIUtil;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import me.drakeet.multitype.MultiTypeAdapter;

import static com.kye.express.utils.ActivityManager.getActivity;

public class IntegralCenterActivity extends BaseToolbarActivity implements IntegralCenterContract.IntegralCenterView, IntegralTabItemViewBinder.OnTabLayoutListenr, IntegralHeaderItemViewBinder.OnIntegralHeaderListener, IntegralRecordObtainItemViewBinder.onItemListener, IntegralRecordExchangeItemViewBinder.OnItemIntegralExchangeListener {

    private static final String DATE_PICKER_DIALOG = "DATE_PICKER_DIALOG";
    private IntegralCenterContract.IntegralCenterPresenter presenter;
    private ActivityIntegralCenterBinding binding;
    private MultiTypeAdapter adapter;
    private IntegralRecordType recordType = IntegralRecordType.TYPE_EXCHANGE;
    protected final int QUERY_DATE_FROM = 0;
    protected final int QUERY_DATE_TO = 1;
    private User userInfo;
    private Dialog dialog;

    public static void startActivity(Context context) {
        checkLogin(context, new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(context, IntegralCenterActivity.class);
                context.startActivity(intent);
            }
        });
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_integral_center);
        presenter = new IntegralCenterContract.IntegralCenterPresenter();
        presenter.bind(this);
        initToolbar();
        initViews();
        initEvents();
        initDataFirst();
    }

    private void initToolbar() {
        setSupportActionBar(binding.toolbar);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        binding.toolbar.setTitleTextColor(getResources().getColor(R.color.white));
        binding.toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }

    private void initViews() {
        binding.integrals.setLayoutManager(new LinearLayoutManager(this));
        HorizontalDividerItemDecoration dividerItemDecoration =
                new HorizontalDividerItemDecoration.Builder(this)
                .color(getResources().getColor(R.color.divider_two))
                        .size((int) UIUtil.convertDpToPx(this, 0.5f))
                        .build();
        binding.integrals.addItemDecoration(dividerItemDecoration);
        adapter = new MultiTypeAdapter();
        adapter.register(IntegralHeaderBean.class, new IntegralHeaderItemViewBinder(this));
        adapter.register(IntegralRecordStatusBean.class, new IntegralTabItemViewBinder(this));
        adapter.register(IntegralRecordExchangeRecordBean.class, new IntegralRecordExchangeItemViewBinder(this));
        adapter.register(IntegralRecordObtainRecordBean.class, new IntegralRecordObtainItemViewBinder(this));
        adapter.register(IntegralRecordEmptyBean.class, new IntegralRecordEmptyItemViewBinder());
        binding.integrals.setAdapter(adapter);

        binding.llErrorServer.tvErrorServerText.setText("未登录");
        binding.llErrorServer.btErrorServerRetry.setVisibility(View.GONE);
    }

    private void initEvents() {
        binding.statusLayout.setOnLoadingListener(new StatusLayout.OnLoadingListener() {
            @Override
            public void onLoading() {
                presenter.refreshIntegralHeaderAndExchangeData();
            }
        });
        binding.refreshLayout.setOnRefreshLoadmoreListener(new OnRefreshLoadmoreListener() {
            @Override
            public void onLoadmore(RefreshLayout refreshlayout) {
                presenter.loadMoreExchangeData();
            }

            @Override
            public void onRefresh(RefreshLayout refreshlayout) {
                presenter.refreshData();
            }
        });
        RxView.clicks(binding.llErrorServer.btErrorServerRetry)
                .compose(this.bindToLifecycleDestroy())
                .compose(new DebounceObservableTransformer<Object>())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {

                    }
                });
    }

    private void initDataFirst() {
        presenter.getUserInfo();
    }

    // ===========

    @Override
    public void refreshIntegralWithExchangeDataViews(List<Object> objects) {
        /**
         * 只有当前数据更新和tab对应才显示更新view,否则更新数据
         */
        binding.refreshLayout.finishRefresh();
        switch (recordType) {
            case TYPE_OBTAIN:
                Logger.d("refreshIntegralWithExchangeDataViews only update datas");
                break;
            case TYPE_EXCHANGE:
                Logger.d("refreshIntegralWithExchangeDataViews update datas and views");
                binding.statusLayout.showContentView();
                adapter.setItems(objects);
                adapter.notifyDataSetChanged();
                binding.refreshLayout.setEnableLoadmore(objects.size() >= PageInfo.SIZE_DEFAULT);
                break;
        }
    }

    @Override
    public void refreshIntegralWithObtainDataViews(List<Object> objects) {
        /**
         * 只有当前数据更新和tab对应才显示更新view,否则更新数据
         */
        binding.refreshLayout.finishRefresh();
        switch (recordType) {
            case TYPE_EXCHANGE:
                Logger.d("refreshIntegralWithObtainDataViews only update datas");
                break;
            case TYPE_OBTAIN:
                Logger.d("refreshIntegralWithObtainDataViews update datas and views");
                binding.statusLayout.showContentView();
                adapter.setItems(objects);
                adapter.notifyDataSetChanged();
                break;
        }
    }

    @Override
    public void loadMoreIntegralExchangeData(List<Object> integralListWithExchangeDatas, List<Object> exchangeDatas) {
        binding.refreshLayout.finishLoadmore();
        /**
         * 只有当前数据加载更多为兑换记录，才会刷新data和view
         * 否则只更新数据
         */
        int startPosition = integralListWithExchangeDatas.size();
        integralListWithExchangeDatas.addAll(exchangeDatas);
        switch (recordType) {
            case TYPE_EXCHANGE:
                Logger.d("loadMoreIntegralExchangeData update data and view");
                adapter.notifyItemRangeInserted(startPosition, integralListWithExchangeDatas.size());
                break;
            case TYPE_OBTAIN:
                Logger.d("loadMoreIntegralExchangeData update data only");
                break;
        }
    }

    @Override
    public void updateQueryIntegralObtainData(ArrayList<Object> datas, int oldSize) {
        adapter.setItems(datas);
        if (datas.size() > 2) {
            adapter.notifyItemRangeChanged(2, datas.size());
        } else if (oldSize > 2) {
            adapter.notifyItemRangeRemoved(2, oldSize);
        }
    }

    @Override
    public void onTabSelect(int position, IntegralRecordStatusBean item) {
        Logger.d("onTabSelect : " + GsonUtils.toJsonString(item));
        presenter.switchToTab(position, item);
    }

    @Override
    public void onTabReselect(int position, IntegralRecordStatusBean item) {
        Logger.d("onTabReselect : " + GsonUtils.toJsonString(item));
        presenter.switchToTab(position, item);
    }

    private void showDateSelectDialog(@IntRange(from = 0, to = 1) final int type, final IntegralRecordStatusBean item) {
        int year;
        int monthOfYear;
        int dayOfMonth;
        Calendar calendar = Calendar.getInstance();
        if (type == QUERY_DATE_FROM) {
            calendar = DateUtils.dateStringToCalendarYMD(item.dateFrom);
        } else {
            calendar = DateUtils.dateStringToCalendarYMD(item.dateTo);
        }
        year = calendar.get(Calendar.YEAR);
        monthOfYear = calendar.get(Calendar.MONTH);
        dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
        DatePickerDialog datePickerDialog = DatePickerDialog.newInstance(
                new DatePickerDialog.OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.set(year, monthOfYear, dayOfMonth);
                        switch (type) {
                            case QUERY_DATE_FROM:
                                onSelectQueryDateFrom(calendar, item);
                                break;
                            case QUERY_DATE_TO:
                                onSelectQueryDateTo(calendar, item);
                                break;
                        }
                    }
                },
                year,
                monthOfYear,
                dayOfMonth
        );
        datePickerDialog.vibrate(true);
        datePickerDialog.setVersion(DatePickerDialog.Version.VERSION_1);
        datePickerDialog.showYearPickerFirst(true);
        datePickerDialog.show(getFragmentManager(), DATE_PICKER_DIALOG);
    }

    private void onSelectQueryDateFrom(final Calendar calendarFrom, final IntegralRecordStatusBean item) {
        Observable.just(item.dateTo)
                .map(new Function<String, Date>() {
                    @Override
                    public Date apply(String s) throws Exception {
                        return DateUtils.dateStringToCalendarYMD(s).getTime();
                    }
                })
                .subscribeOn(Schedulers.io())
                .map(new Function<Date, Calendar>() {
                    @Override
                    public Calendar apply(Date date) throws Exception {
                        return DateUtils.dateToCalendar(date);
                    }
                })
                .map(new Function<Calendar, Boolean>() {
                    @Override
                    public Boolean apply(Calendar calendarTo) throws Exception {
                        return DateUtils.testLeftLessOrEqualToRight(calendarFrom, calendarTo);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        if (aBoolean) {
                            item.setDateFrom(DateUtils.getDateStringByDateYearMonthDay(calendarFrom.getTime()));
                            adapter.notifyItemChanged(1);
                        }
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        Logger.d("select date : " + aBoolean + " , date : " + DateUtils.getDateStringByDateYearMonthDay(calendarFrom.getTime()));
                        if (!aBoolean) {
                            ToastManager.show(getActivity(), "日期错误", Toast.LENGTH_SHORT);
                        } else {

                        }
                    }
                });
    }

    private void onSelectQueryDateTo(final Calendar calendarTo, final IntegralRecordStatusBean item) {
        Observable.just(item.dateTo)
                .map(new Function<String, Date>() {
                    @Override
                    public Date apply(String s) throws Exception {
                        return DateUtils.dateStringToCalendarYMD(s).getTime();
                    }
                })
                .subscribeOn(Schedulers.io())
                .map(new Function<Date, Calendar>() {
                    @Override
                    public Calendar apply(Date date) throws Exception {
                        return DateUtils.dateToCalendar(date);
                    }
                })
                .map(new Function<Calendar, Boolean>() {
                    @Override
                    public Boolean apply(Calendar calendarFrom) throws Exception {
                        return DateUtils.testLeftLessOrEqualToRight(calendarFrom, calendarTo);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        if (aBoolean) {
                            item.setDateTo(DateUtils.getDateStringByDateYearMonthDay(calendarTo.getTime()));
                            adapter.notifyItemChanged(1);
                        }
                    }
                })
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        Logger.d("select date : " + aBoolean + " , date : " + DateUtils.getDateStringByDateYearMonthDay(calendarTo.getTime()));
                        if (!aBoolean) {
                            ToastManager.show(getActivity(), "日期错误", Toast.LENGTH_SHORT);
                        } else {

                        }
                    }
                });
    }

    @Override
    public void onSelectDateFrom(IntegralRecordStatusBean item) {
        showDateSelectDialog(0, item);
    }

    @Override
    public void onSelectDateTo(IntegralRecordStatusBean item) {
        showDateSelectDialog(1, item);
    }

    /**
     * todo :
     * @param item
     */
    @Override
    public void onSelectDate(IntegralRecordStatusBean item) {
        showDateSelectDialog(item);
    }

    private void showDateSelectDialog(IntegralRecordStatusBean item) {
        int year;
        int monthOfYear;
        int dayOfMonth;
        Calendar calendar = Calendar.getInstance();
        calendar = DateUtils.dateStringToCalendarYMD(item.date);
        year = calendar.get(Calendar.YEAR);
        monthOfYear = calendar.get(Calendar.MONTH);
        dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
        DatePickerDialog datePickerDialog = DatePickerDialog.newInstance(
                new DatePickerDialog.OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.set(year, monthOfYear, dayOfMonth);
                        onSelectQueryDate(calendar, item);
                    }
                },
                year,
                monthOfYear,
                dayOfMonth
        );
        datePickerDialog.vibrate(true);
        datePickerDialog.setVersion(DatePickerDialog.Version.VERSION_1);
        datePickerDialog.showYearPickerFirst(true);
        datePickerDialog.setMaxDate(Calendar.getInstance());
        datePickerDialog.show(getFragmentManager(), DATE_PICKER_DIALOG);
    }

    private void onSelectQueryDate(Calendar calendar, IntegralRecordStatusBean item) {
        item.setDate(DateUtils.getDateStringByDateYearMonthDay(calendar.getTime()));
        presenter.refreshIntegralHeaderAndObtainData();
    }

    @Override
    public void onQueryIntegralObtainData(IntegralRecordStatusBean item) {
        Logger.d("onQueryIntegralObtainData : " + GsonUtils.toJsonString(item, true));
        presenter.refreshIntegralHeaderAndObtainData();
    }

    @Override
    public void showIntegralObtainData(ArrayList<Object> objects) {
        adapter.setItems(objects);
        adapter.notifyDataSetChanged();
    }

    @Override
    public void showIntegralExchangeData(ArrayList<Object> objects) {
        adapter.setItems(objects);
        adapter.notifyDataSetChanged();
    }

    @Override
    public void showLoading() {

    }

    @Override
    public void dismissLoading() {

    }

    /**
     * todo : 积分处理
     * @param result
     * @param integralHeaderBean
     */
    @Override
    public void updateIntegralByUserSuccess(OpenApiResult<IntegralUpdateByUser> result, IntegralHeaderBean integralHeaderBean) {
        if (result.getCode() == 0) {
            ToastManager.show(getApplicationContext(), "签到成功 +30积分");
        } else {
            ToastManager.show(getApplicationContext(), result.getMsg());
        }
        integralHeaderBean.setIntegralUpdateByUser(result.getData());
        integralHeaderBean.setIntegralUpdateSuccess(true);
        adapter.notifyItemChanged(0);
    }

    @Override
    public void updateIntegralByUserFailed(OpenApiResult<IntegralUpdateByUser> result) {
        adapter.notifyItemChanged(0);
        ToastManager.show(getApplicationContext(), result.getMsg());
    }

    @Override
    public void updateIntegralByUserFailed(String message) {
        adapter.notifyItemChanged(0);
        ToastManager.show(getApplicationContext(), message);
    }

    @Override
    public void onUser(User userInfo) {
        this.userInfo = userInfo;
    }

    /**
     * 签名
     * @param item
     */
    @Override
    public void onSignClicked(IntegralHeaderBean item) {
        Logger.d("onSignClicked : " + GsonUtils.toJsonString(item));
        presenter.updateIntegralByUser(item);
    }

    /**
     * 花积分
     * @param item
     */
    @Override
    public void onConsumeClicked(IntegralHeaderBean item) {
        Logger.d("onConsumeClicked : " + GsonUtils.toJsonString(item));
        finish();
    }

    /**
     * 积分攻略
     * @param item
     */
    @Override
    public void onStrategyClicked(IntegralHeaderBean item) {
        Logger.d("onStrategyClicked : " + GsonUtils.toJsonString(item));
        IntegralStrategyActivity.startActivity(this);
    }

    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
    }

    @Override
    public void onItemIntegralObtainClicked(IntegralRecordObtainRecordBean item) {
        if (item.getIntegralType().equals(IntegralObtainType.TYPE_PZJF001.getType())
//                || item.getIntegralType().equals(IntegralObtainType.TYPE_YCJF001.getType())
                || item.getIntegralType().equals(IntegralObtainType.TYPE_YWJF001.getType())) {
            Logger.d("onItemIntegralObtainClicked to detail : " + GsonUtils.toJsonString(item, true));
            /**
             * 查看积分明细
             */
            if (item.getIntegralType().equals(IntegralObtainType.TYPE_PZJF001.getType())) {
                IntegralItemListActivity.startActivity(this, item.getIntegralTime(), IntegralItemType.PHOTO);
            } else if (item.getIntegralType().equals(IntegralObtainType.TYPE_YWJF001.getType())) {
                IntegralItemListActivity.startActivity(this, item.getIntegralTime(), IntegralItemType.BUSINESS);
            }
        } else {
            Logger.d("onItemIntegralObtainClicked not to detail : " + GsonUtils.toJsonString(item, true));
        }
    }

    @Override
    public void onItemIntegralExchangeClicked(IntegralRecordExchangeRecordBean item) {
        Logger.d("onItemIntegralExchangeClicked : " + GsonUtils.toJsonString(item, true));
        if (TextUtils.isEmpty(item.getActiveAddress())) {
            /**
             * todo : 跳转到京东详情
             */
            JDOrderDetailModel orderDetailModel = new JDOrderDetailModel();
            orderDetailModel.setAddress(item.getAddress());
            orderDetailModel.setCompany(item.getMerchantno());
            orderDetailModel.setGoodsName(item.getGoodsNeme());
            orderDetailModel.setImageUrl(item.getPicture());
            orderDetailModel.setIntegralTaken(String.valueOf(item.getIntegral()));
            orderDetailModel.setLogisticsInfo("");
            orderDetailModel.setMobile(item.getMobile());
            orderDetailModel.setName(item.getName());
            orderDetailModel.setOrderCode(item.getGoodsId());
            orderDetailModel.setOrderState(item.getState());
            orderDetailModel.setOrderTime(item.getTime());
            orderDetailModel.setSkuId(item.getSku());
            JDOrderDetailActivity.startActivity(this, orderDetailModel);
        } else {
            /**
             * todo : 跳转到网页 activeAddress
             */
        }
    }

    @Override
    public ActivityIntegralCenterBinding getBinding() {
        return binding;
    }

    @Override
    public void enableLoadMore() {
        binding.refreshLayout.setEnableLoadmore(true);
    }

    @Override
    public void disableLoadMore() {
        binding.refreshLayout.setEnableLoadmore(false);
    }

    @Override
    public void enableRefresh() {
        binding.refreshLayout.setEnableRefresh(true);
    }

    @Override
    public void disableRefresh() {
        binding.refreshLayout.setEnableRefresh(false);
    }

    @Override
    public IntegralRecordType getRecordType() {
        return recordType;
    }

    @Override
    public void setRecordType(IntegralRecordType recordType) {
        this.recordType = recordType;
    }

    @Override
    public void showLoadingDialog() {
        dialog = KyeProgressDialog.show(this, dialog);
        dialog.setCancelable(false);
    }

    @Override
    public void dimissLoadingDialog() {
        KyeProgressDialog.dismiss(dialog);
    }
}
